#ifndef _EK_SCHED_H_
#define _EK_SCHED_H_

/* The monitor interface */
void refresh_envs_monitor(void);

/* The scheduler interface */
struct scheduler_t
{
	 /* point to the implement-accociated data */
	 void *data;
	 /* get the next ready env idx, args: data, hint */
	 int (*get_sched_next)(void *, int);
	 int (*sleep)(void *, uint16_t);
	 int (*wakeup)(void *, uint16_t);
	 int (*attach)(void *, uint16_t, uint16_t);
	 int (*detach)(void *);
};

/* hint -- called by real irq0 */
#define SCHED_HINT_PERIOD 0
/* hint -- called by user that really want to be switched out */
#define SCHED_HINT_FORCE  1

/* a more humility routine to lock a spin-lock */
void sl_lock(volatile uint8_t *lock);

/* initialize the scheduler */
int sch_init(void);

/* turn into sleep */
int sch_sleep(uint16_t head, volatile uint8_t *lock);
/* wake up */
int sch_wakeup(uint16_t idx, volatile uint8_t *lock);
/* insert a new env idx to the schedular */
int sch_attach(uint16_t ori, uint16_t idx);
/* detach the env itself */
int sch_detach(void);
/* yield request */
void sch_yield(uint16_t status);


/* current executing environment */
extern int cur_env;
/* spin lock of scheduling */
extern uint8_t envs_switch_lock;

#endif /* _EK_SCHED_H_ */
